import { Inject, Controller, Get, Query, Post, Body } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { PREFIX } from '../contanst';
import { BaseController } from './base.controller';
import { InventoryService } from '../service/inventory.service';
import { OrdersService } from '../service/orders.service';
import { OutboundService } from '../service/outbound.service';
import { OrdersProductsMapService } from '../service/ordersProductsMap.service';
import { ErpOrdersService } from '../service/erpOrders.service';
import { divide, minus, plus, times } from '../utils/math';
import { COST_AMOUNT, COST_RATE } from '../contanst/inventory';
import { DailyReportService } from '../service/dailyReport.service';
import { cloneDeep } from 'lodash';
import { Like } from 'typeorm';

const DESCRIPTION = '报表';
@Controller(PREFIX)
export class APIController extends BaseController {
  @Inject()
  ctx: Context;

  @Inject()
  inventoryService: InventoryService;

  @Inject()
  ordersService: OrdersService;

  @Inject()
  outboundService: OutboundService;

  @Inject()
  ordersProductsMapService: OrdersProductsMapService;

  @Inject()
  erpOrdersService: ErpOrdersService;

  @Inject()
  dailyReportService: DailyReportService;

  @Get('/daily', {
    description: `${DESCRIPTION}-日报`,
  })
  async index(
    @Query('data_date') data_date,
    @Query('size') size = 10,
    @Query('page') page = 1,
    @Query('store_name') store_name,
    @Query('order_number') order_number,
    @Query('product_id') product_id
  ) {
    const list = await this.dailyReportService.page({
      data: {
        data_date,
        size,
        page,
        store_name: store_name && Like(`%${store_name}%`),
        order_number: order_number && Like(`%${order_number}%`),
        product_info: product_id && Like(`%${product_id}%`),
      },
    });

    return this.success(list);
  }

  @Post('/daily', {
    description: `${DESCRIPTION}-生成日报`,
  })
  async create(@Body('data_date') data_date, @Body('store_name') store_name) {
    if (!data_date) {
      return this.error('请选择日期');
    }
    if (!store_name) {
      return this.error('请选择店铺');
    }
    const list = await this.dailyReportService.list({
      data: { data_date, store_name },
    });

    if (list.length) {
      return this.success(list);
    }

    const ordersProducts = await this.ordersProductsMapService.list({
      data: { data_date, store_name },
    });
    const inventory = await this.inventoryService.list({
      orderData: {
        warehousing_time: 'ASC',
      },
    });
    const inventoryUpdateList: any[] = [];
    const outbound: any[] = [];
    console.log('ordersProducts', ordersProducts);

    ordersProducts.forEach(order => {
      const cloneOrder = cloneDeep(order);
      // 订单商品总数量
      let order_num = times(
        cloneOrder.product_quantity,
        cloneOrder.product_specification
      );

      const list = inventory
        .filter(item => item.product_code === cloneOrder.product_code)
        .map(item => {
          return {
            id: item.id,
            ...item,
          };
        });

      for (let index = 0; index < list.length; index++) {
        const record: any = cloneDeep(list[index]);
        // 剩余库存量 大于等于 订单商品总数量 则当前直接出库否则找下一条，直到满足订单商品总数量
        const inventory_id = record.id;

        if (record.remaining_inventory_quantity >= order_num) {
          const remaining_inventory_quantity =
            record.remaining_inventory_quantity - order_num;
          // 出库数量
          const outbound_product_quantity = order_num;
          order_num = 0;

          inventoryUpdateList.push({
            ...record,
            id: inventory_id,
            remaining_inventory_quantity,
          });

          const order_id = order.id;
          const inventory_product_quantity = record.product_quantity;
          const order_product_quantity = cloneOrder.product_quantity;
          delete record.id;
          delete cloneOrder.id;

          outbound.push({
            ...record,
            ...cloneOrder,
            inventory_id,
            order_id,
            remaining_inventory_quantity,
            inventory_product_quantity,
            order_product_quantity,
            outbound_product_quantity,
          });
          break;
        } else {
          order_num = order_num - record.remaining_inventory_quantity;
          record.remaining_inventory_quantity = 0;
          inventoryUpdateList.push({
            ...record,
            id: inventory_id,
            remaining_inventory_quantity: 0,
          });
          const order_id = cloneOrder.id;
          const inventory_product_quantity = record.product_quantity;
          const order_product_quantity = cloneOrder.product_quantity;
          // 出库数量
          const outbound_product_quantity = inventory_product_quantity;
          delete record.product_quantity;
          delete cloneOrder.product_quantity;
          delete record.id;
          delete cloneOrder.id;
          outbound.push({
            ...record,
            ...cloneOrder,
            inventory_id,
            order_id,
            remaining_inventory_quantity: 0,
            inventory_product_quantity,
            order_product_quantity,
            outbound_product_quantity,
          });
        }
      }
    });

    this.inventoryService.upsert(inventoryUpdateList);
    this.outboundService.add(outbound);

    // 商品成本计算列表
    const product_cost_list: any[] = [];
    // 商品成本计算
    outbound.forEach(item => {
      // 单价 （成本价 / 箱规）
      const unit_price = item.unit_price || 0;
      // 出库数量
      const outbound_product_quantity = item.outbound_product_quantity || 0;
      // 进货数量
      const inventory_product_quantity = item.inventory_product_quantity || 0;
      // 成本 =（成本价 / 箱规）* 规格 * 商品数量 = 单价 * 出库数量
      const cost = times(unit_price, outbound_product_quantity);
      // 打款金额
      const payment_amount = item.payment_amount || 0;
      // 打款单价
      const payment_unit_price = divide(payment_amount, item.box_gauge);
      // 打款成本
      const payment_cost = times(payment_unit_price, outbound_product_quantity);
      // 箱规
      const box_gauge = item.box_gauge || 0;
      // 初始进货数量
      const init_inventory_quantity = times(
        box_gauge,
        inventory_product_quantity
      );
      // 费用： 1、比例：（成本价 / 箱规）* 费用比例 * 规格 * 商品数量
      //       2、金额：（费用金额 /（箱规 * 进货数量））* 规格 * 商品数量
      let extra_cost = 0;
      JSON.parse(item.cost_params)?.forEach?.(k => {
        if (String(k.type) === COST_AMOUNT) {
          const cost = divide(
            k.cost,
            times(init_inventory_quantity, outbound_product_quantity)
          );

          extra_cost = plus(extra_cost, cost);
        }
        if (String(k.type) === COST_RATE) {
          const cost = times(
            times(unit_price, outbound_product_quantity),
            k.cost
          );

          extra_cost = plus(extra_cost, cost);
        }
      });

      // 返利比例
      const rebate_rate = item.rebate_rate || 0;
      // 返利 = （打款价 / 箱规） * 规格 * 商品数量 * 返利比例
      const rebate = times(
        divide(item.payment_amount, box_gauge),
        times(rebate_rate, outbound_product_quantity)
      );

      product_cost_list.push({
        rebate,
        extra_cost,
        cost,
        payment_cost,
        product_code: item.product_code,
        product_name: item.product_name,
        product_id: item.product_id,
        order_number: item.order_number,
      });
    });
    const orders = await this.ordersService.all({
      data_date,
      store_name,
    });
    console.log('orders', orders);

    const daily_report_list: any = [];
    const calcFn = async (order: any) => {
      const order_number = order.order_number;
      const erpOrders = await this.erpOrdersService.list({
        data: { order_number },
      });

      // 运费
      let erp_cost = 0;
      // 一个订单有多个erp运单
      if (erpOrders.length > 1) {
        erpOrders.forEach(item => {
          erp_cost = plus(erp_cost, item.cost);
        });
      }
      // 查一个erp运单存在多个订单情况
      if (erpOrders.length === 1) {
        const erp_order_number = erpOrders[0]?.erp_order_number;
        const cost = erpOrders[0]?.cost;

        const res = await this.erpOrdersService.list({
          data: {
            erp_order_number,
          },
        });

        const len = res.length;
        erp_cost = divide(cost, len) || 0;
      }

      if (erp_cost === 0) {
        console.log('erpOrders', erpOrders, order_number);
      }

      // 商品成本
      let product_cost = 0;
      // 打款成本
      let payment_cost = 0;
      // 费用
      let extra_cost = 0;
      // 返利
      let rebate = 0;
      const product_cost_arr = product_cost_list.filter(
        item => item.order_number === order_number
      );

      product_cost_arr.forEach(item => {
        product_cost = plus(product_cost, item.cost);
        payment_cost = plus(payment_cost, item.cost);
        extra_cost = plus(extra_cost, item.extra_cost);
        rebate = plus(rebate, item.rebate);
      });
      // 订单应付金额
      const order_payable_amount = order.order_payable_amount || 0;
      const actual_platform_discount = order.actual_platform_discount || 0;
      const actual_discount_amount_by_merchant =
        order.actual_discount_amount_by_merchant || 0;
      // 订单收益 = 订单应付金额 +平台实际承担优惠金额 + 商家实际承担优惠金额
      const income = plus(
        order_payable_amount,
        plus(actual_platform_discount, actual_discount_amount_by_merchant)
      );
      // 订单总收益 = 订单应付金额 + 平台实际承担优惠金额 + 商家实际承担优惠金额 + 费用 + 返利
      const total_revenue = plus(income, plus(extra_cost, rebate));

      // 流量体裁比例 流量体载 === 商品卡 ？ 0.6% ： 2.5%
      const fee_rate = order.traffic_genres === '商品卡' ? 0.006 : 0.025;
      //  平台服务费 =（订单应付金额 + 平台实际承担优惠金额 + 商家实际承担优惠金额）*（流量体载 === 商品卡 ？ 0.6% ： 2.5%）
      const service_fee = income * fee_rate;
      // 团长服务费
      const team_leader_service_fee =
        order?.teamLeaderServiceFee?.service_fee || 0;
      // 达人佣金
      const expert_commission = order?.expert_commission?.commission || 0;
      const fee_sum = plus(expert_commission, team_leader_service_fee);
      // 订单总成本 = 商品成本 + 平台服务费 + 达人佣金 + 团长服务费 + 运费
      const total_cost = plus(
        product_cost,
        plus(erp_cost, plus(fee_sum, service_fee))
      );

      // 利润 = （订单应付金额 + 平台实际承担优惠金额 + 商家实际承担优惠金额 + 费用 + 返利  ） - （成本 + 平台服务费 + 达人佣金 + 团长服务费 + 运费 ）
      const profit = minus(total_revenue, total_cost);
      const order_num = times(
        order.product_quantity,
        order.product_specification
      );

      const cpOrder = cloneDeep(order);
      delete cpOrder.id;

      daily_report_list.push({
        ...cpOrder,
        actual_discount_amount_by_merchant,
        profit,
        order_number,
        product_info: JSON.stringify(product_cost_arr),
        oreder_revenue: total_revenue,
        oreder_cost: total_cost,
        erp_cost,
        platform_service_fee: service_fee,
        commission: expert_commission,
        service_fee: team_leader_service_fee,
        extra_cost,
        rebate,
        order_num,
        product_cost,
        payment_cost,
      });
    };
    const calcList = orders.map(order => calcFn(order));
    await Promise.all(calcList);

    this.dailyReportService.add(daily_report_list);
    return this.success();
  }

  @Get('/daily/summary', {
    description: `${DESCRIPTION}-日报汇总表`,
  })
  async summary(@Query('data_date') data_date) {
    const list = await this.dailyReportService.summary(data_date);
    return this.success(list);
  }
}
